package com.file.manage.infrastructure.aop;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


@Aspect
@Component
@Slf4j
public class WebLogAspect {

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("@annotation(com.file.manage.infrastructure.aop.WebLog)")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                startTime.set(System.currentTimeMillis());
                String args = JSONUtil.toJsonStr(joinPoint.getArgs());
                if (args != null && args.length() > 2000) {
                    args = args.substring(0, 2000);
                }
                log.info("【controller日志】请求 url : {} , http_method :{} , IP : {} , class_method : {} , args : {}",
                        request.getRequestURL().toString(),
                        request.getMethod(),
                        request.getRemoteAddr(),
                        joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(),
                        args

                );
            }
        } catch (Exception e) {
            log.error("weblog doBefore Exception,cause = {}", e.getMessage(), e);
        }
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) {
        try {
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                String url = request.getRequestURL().toString();

                if (StrUtil.isNotEmpty(url) && startTime != null && startTime.get() != null) {
                    log.info("【controller日志】响应  url : {} , spend time : {} 毫秒", url, (System.currentTimeMillis() - startTime.get()));
                }

                // 使用完后清除，避免线程池污染value
                if (startTime != null) startTime.remove();
            }
        } catch (Exception e) {
            log.error("weblog doAfterReturning Exception,cause = {}", e.getMessage(), e);
        }
    }

}
